import mongoose from 'mongoose';
import assert from 'assert';
import _ from 'lodash';
import log4js from 'koa-log4';
import componentContainer from '../../components/componentContainer';

const skynetMessageLogger = log4js.getLogger('skynetMessage');
class SkynetMessage {
  constructor() {
    this.endpointMapping = {
      'sky1.97kid.com': '192.168.20.239',
      'skynet1.97kid.com': '192.168.2.46',
      'skynet2.97kid.com': '192.168.2.91',
      'skynet3.97kid.com': '192.168.20.17',
      'skynet4.97kid.com': '192.168.20.98',
      'skynet5.97kid.com': '192.168.20.219',
    };
  }

  shouldPushToSkynet(message, customer) {
    return message.subType === 'text' && customer && customer.isTeacher() && customer.id !== message.fromUser.id;
  }

  async getEndPoint(teacherIdInSkynet, redis) {
    let endpoint;
    const keys = Object.keys(this.endpointMapping);
    for (const key of keys) {
      // eslint-disable-next-line
      const ret = await redis.sismember(`skynet:${key}:online`, teacherIdInSkynet);
      if (ret) endpoint = this.endpointMapping[key];
    }

    return endpoint ? `http://${endpoint}:7111/roomevent` : null;
  }

  async handle({ message, user }) {
    const ChannelModel = mongoose.model('Channel');
    const channel = await ChannelModel.findById(message.toChannel).populate('customer');

    if (!this.shouldPushToSkynet(message, channel.customer)) return null;

    const teacherJiuquId = channel.customer.getTeacherJqId();
    const apiBridge = componentContainer.getApiBridge();
    const redis = componentContainer.getRedis();

    const teacherIdInSkynet = `t_${teacherJiuquId}`;
    const skynetRoomAt = await redis.hget('teacher:online:skynet', teacherIdInSkynet);

    // 教师不在房间内
    if (!skynetRoomAt) return null;

    const endpoint = await this.getEndPoint(teacherIdInSkynet, redis);
    assert(endpoint, `Skynet roomAt exist, but can't not find match endpoint ${teacherIdInSkynet}`);

    skynetMessageLogger.debug('Receive teacher message, try to forward to skynet', teacherIdInSkynet);
    const parsedMessage = `${_.upperFirst(user.username)} says:\n    ${message.body}`;
    return apiBridge.sendMessageToSkynet(skynetRoomAt, parsedMessage, endpoint);
  }
}

export default new SkynetMessage();
